package com.wenx.v3system.modular.platform.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.wenx.base.rest.BaseRestController;
import com.wenx.v3core.response.R;
import com.wenx.v3secure.annotation.RequiresPermissions;
import com.wenx.v3secure.enums.PlatformPermission;
import com.wenx.v3system.modular.platform.domain.dto.PlatformRoleDto;
import com.wenx.v3system.modular.platform.domain.query.PlatformRoleQuery;
import com.wenx.v3system.modular.platform.service.PlatformRoleService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.io.Serializable;
import java.util.List;

import static com.wenx.v3secure.annotation.RequiresPermissions.Logical.OR;

/**
 * 平台角色管理控制器
 * 简化后的角色管理API
 * 
 * @author wenx
 */
@Slf4j
@RestController
@RequestMapping("/api/v3/platform/roles")
@Tag(name = "平台角色管理", description = "平台角色管理相关接口")
public class PlatformRoleRestController extends BaseRestController<PlatformRoleDto, PlatformRoleQuery, PlatformRoleService> {

    public PlatformRoleRestController(PlatformRoleService service) {
        super(service);
    }

    @Override
    @PostMapping("/page")
    @Operation(summary = "分页查询角色", description = "分页查询平台角色列表")
    @RequiresPermissions(value = {PlatformPermission.PLATFORM_ALL_CODE, PlatformPermission.PLATFORM_ROLE_READ_CODE}, logical = OR)
    public R page(@RequestBody @Valid PlatformRoleQuery query) {
        IPage<?> result = service.page(query);
        return R.ok(result);
    }

    @Override
    @GetMapping("/get/{id}")
    @Operation(summary = "根据ID获取角色", description = "根据ID获取角色详情")
    @RequiresPermissions(value = {PlatformPermission.PLATFORM_ALL_CODE, PlatformPermission.PLATFORM_ROLE_READ_CODE}, logical = OR)
    public R get(@PathVariable Serializable id) {
        Object result = service.get(id);
        return R.ok(result);
    }

    @Override
    @PostMapping("/add")
    @Operation(summary = "添加角色", description = "创建新的自定义角色")
    @RequiresPermissions(value = {PlatformPermission.PLATFORM_ALL_CODE, PlatformPermission.PLATFORM_ROLE_ALL_CODE}, logical = OR)
    public R add(@RequestBody @Valid PlatformRoleDto dto) {
        service.add(dto);
        return R.ok("角色创建成功");
    }

    @Override
    @PutMapping("/update")
    @Operation(summary = "更新角色", description = "更新角色信息")
    @RequiresPermissions(value = {PlatformPermission.PLATFORM_ALL_CODE, PlatformPermission.PLATFORM_ROLE_ALL_CODE}, logical = OR)
    public R update(@RequestBody @Valid PlatformRoleDto dto) {
        service.update(dto);
        return R.ok("角色更新成功");
    }

    @Override
    @DeleteMapping("/delete/{id}")
    @Operation(summary = "删除角色", description = "删除自定义角色")
    @RequiresPermissions(value = {PlatformPermission.PLATFORM_ALL_CODE, PlatformPermission.PLATFORM_ROLE_ALL_CODE}, logical = OR)
    public R delete(@PathVariable Serializable id) {
        service.delete(Long.valueOf(id.toString()));
        return R.ok("角色删除成功");
    }

    // 扩展接口
    @GetMapping("/all")
    @Operation(summary = "获取所有角色", description = "获取所有角色（包括内置和自定义）")
    @RequiresPermissions(value = {PlatformPermission.PLATFORM_ALL_CODE, PlatformPermission.PLATFORM_ROLE_READ_CODE}, logical = OR)
    public R getAllRoles() {
        List<PlatformRoleDto> roles = service.getAllRoles();
        return R.ok(roles);
    }

    @GetMapping("/builtin")
    @Operation(summary = "获取内置角色", description = "获取系统内置角色列表")
    @RequiresPermissions(value = {PlatformPermission.PLATFORM_ALL_CODE, PlatformPermission.PLATFORM_ROLE_READ_CODE}, logical = OR)
    public R getBuiltinRoles() {
        List<PlatformRoleDto> roles = service.getBuiltinRoles();
        return R.ok(roles);
    }

    @GetMapping("/custom")
    @Operation(summary = "获取自定义角色", description = "获取用户自定义角色列表")
    @RequiresPermissions(value = {PlatformPermission.PLATFORM_ALL_CODE, PlatformPermission.PLATFORM_ROLE_READ_CODE}, logical = OR)
    public R getCustomRoles() {
        List<PlatformRoleDto> roles = service.getCustomRoles();
        return R.ok(roles);
    }

    @GetMapping("/code/{code}")
    @Operation(summary = "根据编码获取角色", description = "根据角色编码获取角色详情")
    @RequiresPermissions(value = {PlatformPermission.PLATFORM_ALL_CODE, PlatformPermission.PLATFORM_ROLE_READ_CODE}, logical = OR)
    public R getRoleByCode(@PathVariable String code) {
        PlatformRoleDto role = service.getRoleByCode(code);
        if (role == null) {
            return R.failed("角色不存在");
        }
        return R.ok(role);
    }

    @PutMapping("/status/{id}")
    @Operation(summary = "修改角色状态", description = "启用或禁用角色")
    @RequiresPermissions(value = {PlatformPermission.PLATFORM_ALL_CODE, PlatformPermission.PLATFORM_ROLE_ALL_CODE}, logical = OR)
    public R updateStatus(
            @PathVariable Long id,
            @RequestParam Integer status) {
        try {
            // 获取角色信息
            PlatformRoleDto role = (PlatformRoleDto) service.get(id);
            if (role == null) {
                return R.failed("角色不存在");
            }
            
            // 检查是否为内置角色
            if (Boolean.TRUE.equals(role.getIsBuiltin())) {
                return R.failed("内置角色状态不可修改");
            }
            
            // 更新状态
            role.setStatus(status);
            service.update(role);
            
            String statusText = status == 1 ? "启用" : "禁用";
            return R.ok("角色" + statusText + "成功");
        } catch (Exception e) {
            log.error("修改角色状态失败: id={}, status={}", id, status, e);
            return R.failed("修改角色状态失败: " + e.getMessage());
        }
    }


    @GetMapping("/check-code")
    @Operation(summary = "检查角色编码", description = "检查角色编码是否已存在")
    @RequiresPermissions(value = {PlatformPermission.PLATFORM_ALL_CODE, PlatformPermission.PLATFORM_ROLE_READ_CODE}, logical = OR)
    public R checkCodeExists(
            @RequestParam String code,
            @RequestParam(required = false) Long excludeId) {
        try {
            boolean exists = service.checkCodeExists(code, excludeId);
            return R.ok(exists);
        } catch (Exception e) {
            log.error("检查角色编码失败: code={}", code, e);
            return R.failed("检查角色编码失败: " + e.getMessage());
        }
    }
}